package com.unitd.base.frame.front;

import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;

import java.util.*;

/**
 * 自定义的给前端使用的菜单对象信息对象
 * @filename TreeModel.java
 * @copyright www.unitd.com
 * @author Hudan
 * @version 1.0
 * @date 2019-01-25
 */
public class TreeModel {

	/** 菜单ID */
	private Integer id;
	/** 菜单名称 */
	private String name;
	/** 菜单值 */
	private String value;
	/** 菜单图标 */
	private String icon;
	/** 上级菜单ID */
	private Integer pid;
	/** 上级菜单名称 */
	private String pName;
	/** 是否叶子节点 */
	private boolean leaf;
	/** 是否展开*/
	private boolean spread;
	/** 附加信息 */
	private String extraAttr;
	/** 起始数据 */
	private Object originData;
	/** 子菜单列表 */
	private List<TreeModel> children;

	public TreeModel() {
	}

	public TreeModel(Integer id, String name, String value, String icon, Integer pid, boolean leaf) {
		this.id = id;
		this.name = name;
		this.value = value;
		this.icon = icon;
		this.pid = pid;
		this.leaf = leaf;
	}

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getValue() {
		return value;
	}

	public void setValue(String value) {
		this.value = value;
	}

	public String getIcon() {
		return icon;
	}

	public void setIcon(String icon) {
		this.icon = icon;
	}

	public Integer getPid() {
		return pid == null ? 0 : pid;
	}

	public void setPid(Integer pid) {
		this.pid = pid;
	}

	public String getpName() {
		return pName;
	}

	public void setpName(String pName) {
		this.pName = pName;
	}

	public boolean isLeaf() {
		return leaf;
	}

	public void setLeaf(boolean leaf) {
		this.leaf = leaf;
	}

	public boolean isSpread() {
		return spread;
	}

	public void setSpread(boolean spread) {
		this.spread = spread;
	}

	public String getExtraAttr() {
		return extraAttr;
	}

	public void setExtraAttr(String extraAttr) {
		this.extraAttr = extraAttr;
	}

	public Object getOriginData() {
		return originData;
	}

	public void setOriginData(Object originData) {
		this.originData = originData;
	}

	public void addChild(TreeModel child) {
		getChildren().add(child);
		child.setpName(name);
	}

	public List<TreeModel> getChildren() {
		return children == null ? (children = new ArrayList<>()) : children;
	}

	public void setChildren(List<TreeModel> children) {
		this.children = children;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((id == null) ? 0 : id.hashCode());
		return result;
	}


	@Override
	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj == null) {
			return false;
		}
		if (getClass() != obj.getClass()) {
			return false;
		}

		TreeModel other = (TreeModel) obj;
		if (id == null) {
			if (other.id != null) {
				return false;
			}
		} else if (!id.equals(other.id)) {
			return false;
		}
		return true;
	}

	@Override
	public String toString() {
		return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
	}


	public static TreeModel build(List<TreeModel> models) {
		TreeModel root = new TreeModel();

		//按pid排序
		Collections.sort(models, new Comparator<TreeModel>() {
			@Override
			public int compare(TreeModel o1, TreeModel o2) {
				return o1.getPid().compareTo(o2.getPid());
			}
		});

		Map<Integer, TreeModel> modelMap = new HashMap<>();
		for (TreeModel model : models) {
			if (!model.isLeaf()) {
				modelMap.put(model.getId(), model);
			}
		}
		for (TreeModel model : models) {
			if ((model.getPid() == 0 && !model.isLeaf()) || !modelMap.containsKey(model.getPid())) {
				root.addChild(model);
			} else {
				modelMap.get(model.getPid()).addChild(model);
			}
		}

		return root;
	}
}